/************************************************************************************************
 *   深圳市摩西尔电子有限公司 @版本所有@
 *
 *   此文件为硬件数据读写命令
 *
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 徐烁超
 *      时间 : 2020.11.25
 *      内容 : 所有代码
 *************************************************************************************************/

/* exported mc_hwdata_table */
/* exported mc_hwdata_scroll_fun */

/* global $ */
/* global mc_ui_edit */
/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    数据列表
 * 参数:
 *    @param {Promise<Number>} ui_window_h 外层窗口高度度
 *    @param {Promise<Number>} ui_window_w 外层窗口宽度
 * 返回：
 *    NA
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 徐烁超
 *      时间 : 2020.11.25
 *      内容 : 所有代码
 ************************************************************************************************/
function mc_hwdata_table(ui_window_h,ui_window_w) {
    this.m_ui_window_h = ui_window_h ? ui_window_h : 0;
    this.m_ui_window_w = ui_window_w ? ui_window_w : 0;

    // 数据长度
    var m_ui_data_len = 0;
    // 数据
    var m_ary_data = [];
    // 单行显示长度
    var m_ui_line_len = 1;

    // 储存数据编辑框
    var m_ary_obj_edit_data_list = [];
    // 储存位置编辑框
    var m_ary_obj_edit_idx_list = [];
    // 当前最顶层行坐标
    var m_ui_top_line_idx = 0;
    // 当前表格类型是否为读取表格
    var m_ui_table_type = 1;
    var m_str_box_id = "";

    /* **************************************** API **************************************** */
    /**
     * 存入数据长度
     * @param {Number} ui_data_len 数据长度
     * @returns {Boolean} 存入结果
     */
    this.set_data_len = function (ui_data_len) {
        m_ui_data_len = ui_data_len;
        m_ary_data = [];
        for (var idx_len = 0; idx_len < ui_data_len; idx_len++) {
            m_ary_data.push(["00","00","00","00"]);
        }
        return true;
    };
    /**
     * 存入父盒子id
     * @param {String} str_box_id 父盒子id
     */
    this.set_box_id = function (str_box_id) {
        m_str_box_id = str_box_id;
    };
    /**
     * 获取行数最大显示数
     * @returns {Number} 当前表格最大显示行数
     */
    this.get_max_bottom_line = function () {
        return Math.ceil(m_ui_data_len / m_ui_line_len) - m_ary_obj_edit_idx_list.length;
    };
    /**
     * 存入单行数据数量
     * @param {Number} ui_line_len 单行数据数量
     * @returns {Boolean} 存入结果
     */
    this.set_line_len = function (ui_line_len) {
        m_ui_line_len = ui_line_len;
        return true;
    };
    /**
     * 存入单行数据数量操作dom
     * @param {Number} ui_line_len 单行数据数量
     * @returns {Number} 更新状态(0:重复,1:修改)
     */
    this.set_line_len_dom = function (ui_line_len) {
        if (m_ui_line_len === ui_line_len) {
            return 0;
        }
        // 当前限制显示行数
        var ui_show_line_max = Math.ceil((this.m_ui_window_h + 200) / 25);
        // 列表窗口高度
        var ui_window_height = 25 * Math.ceil(m_ui_data_len / ui_line_len);
        // 最大行显示数量
        var ui_max_line_show = Math.ceil(m_ui_data_len / ui_line_len);

        $("#" + m_str_box_id + " .scroll_len").css("height",ui_window_height + "px");
        $("#" + m_str_box_id + " .edit_list").css("width",(ui_line_len * 100) + "px");
        // 根据当前行显示删除 或 增加数据编辑框
        if (ui_line_len > m_ui_line_len) {
            // 当设置单行长度大于当前当行长度则增加新的数据格子
            // 需要添加缺失编辑框数量(以单组数据长度为单位)
            var ui_add_data_box_cnt = (ui_line_len - m_ui_line_len) * m_ary_obj_edit_idx_list.length;

            // 当最大显示行数小于当前显示行数时 删除多余行数
            if (
                ui_max_line_show <= ui_show_line_max &&
                ui_max_line_show < m_ary_obj_edit_idx_list.length
            ) {
                ui_add_data_box_cnt = (ui_line_len * ui_max_line_show) - (m_ui_line_len * m_ary_obj_edit_idx_list.length);

                var ui_remove_line_cnt = m_ary_obj_edit_idx_list.length - ui_max_line_show;

                for (var idx_rmv_line = 0; idx_rmv_line < ui_remove_line_cnt; idx_rmv_line++) {
                    var obj_line_edit = m_ary_obj_edit_idx_list[m_ary_obj_edit_idx_list.length - 1];
                    var str_rmv_line_edit_id = obj_line_edit.get_dom_id();

                    $("#" + str_rmv_line_edit_id).parent().remove();
                    m_ary_obj_edit_idx_list.pop();
                }
            }
            // 相差数据长度数量
            // 获取当前最后一个的数据下标
            var ui_old_data_idx_end = m_ary_obj_edit_data_list.length / 4;
            var str_add_html = "";

            for (var idx_add_data = 0; idx_add_data < ui_add_data_box_cnt; idx_add_data++) {
                for (var idx_grp = 0; 4 > idx_grp; idx_grp++) {
                    var ary_data = m_ary_data[(ui_old_data_idx_end + idx_add_data)];
                    var obj_edit_data = new mc_ui_edit();

                    obj_edit_data.set_type("hex");
                    obj_edit_data.set_style_width("23px");
                    obj_edit_data.set_style_height("23px");
                    obj_edit_data.set_max_val("ff");
                    obj_edit_data.set_min_val("00");
                    obj_edit_data.set_default_digit(2);

                    obj_edit_data.set_add_attr([["data_idx",(ui_old_data_idx_end + idx_add_data + 1)],["grp_idx",idx_grp]]);

                    // 增加格子的赋值最后可能有空的情况 则设置为不可编辑的编辑框
                    if (ary_data) {
                        var str_edit_val = ary_data[idx_grp];

                        obj_edit_data.set_val(str_edit_val);
                        obj_edit_data.on_val_chg = m_mc_edit_on_val_chg;
                    }
                    if (!m_ui_table_type || !ary_data) {
                        obj_edit_data.set_type("none");
                        obj_edit_data.set_val("");
                        obj_edit_data.set_disabled(true);
                    }
                    str_add_html += obj_edit_data.get_html_txt();
                    m_ary_obj_edit_data_list.push(obj_edit_data);
                }
            }
            $("#" + m_str_box_id + " .edit_list").append(str_add_html);
        } else {
            // 设置显示行数小于当前显示行数则删除多余编辑内容
            var ui_remove_cnt = (m_ui_line_len - ui_line_len) * (m_ary_obj_edit_idx_list.length * 4);
            var ui_add_line_cnt = 0;
            var str_line_html = "";
            var obj_edit_line = {};
            var idx_add_line = 0;
            var ui_end_line_num = 0;
            // 当最大行显示 大于当前显示行数则加入新的显示行数

            if (ui_max_line_show <= ui_show_line_max) {
                if (ui_max_line_show > m_ary_obj_edit_idx_list.length) {
                    ui_remove_cnt = (m_ui_line_len * m_ary_obj_edit_idx_list.length * 4) - (ui_max_line_show * ui_line_len * 4);
                    ui_add_line_cnt = ui_max_line_show - m_ary_obj_edit_idx_list.length;
                    str_line_html = "";

                    for (idx_add_line = 0; idx_add_line < ui_add_line_cnt; idx_add_line++) {
                        ui_end_line_num = m_ui_top_line_idx + m_ary_obj_edit_idx_list.length;
                        // 生成行下标编辑框内容从0开始生成
                        obj_edit_line = new mc_ui_edit();

                        obj_edit_line.set_style_width("58px");
                        obj_edit_line.set_style_height("23px");
                        obj_edit_line.set_disabled(true);
                        obj_edit_line.set_val(ui_end_line_num.toString(16));
                        str_line_html += obj_edit_line.get_html_txt();
                        m_ary_obj_edit_idx_list.push(obj_edit_line);
                    }
                    $("#" + m_str_box_id + " .data_line_idx").append(str_line_html);
                }
            } else {
                // 否则 不允许显示行数小于限制窗口数量
                if (ui_show_line_max > m_ary_obj_edit_idx_list.length) {
                    ui_remove_cnt = (m_ui_line_len * m_ary_obj_edit_idx_list.length * 4) - (ui_show_line_max * ui_line_len * 4);
                    ui_add_line_cnt = ui_show_line_max - m_ary_obj_edit_idx_list.length;
                    str_line_html = "";

                    for (idx_add_line = 0; idx_add_line < ui_add_line_cnt; idx_add_line++) {
                        ui_end_line_num = m_ui_top_line_idx + m_ary_obj_edit_idx_list.length;
                        // 生成行下标编辑框内容从0开始生成
                        obj_edit_line = new mc_ui_edit();

                        obj_edit_line.set_style_width("58px");
                        obj_edit_line.set_style_height("23px");
                        obj_edit_line.set_disabled(true);
                        obj_edit_line.set_val(ui_end_line_num.toString(16));
                        str_line_html += obj_edit_line.get_html_txt();
                        m_ary_obj_edit_idx_list.push(obj_edit_line);
                    }
                    $("#" + m_str_box_id + " .data_line_idx").append(str_line_html);
                }
            }

            for (var idx_remove = 0; idx_remove < ui_remove_cnt; idx_remove++) {
                var obj_remove_edit = m_ary_obj_edit_data_list[m_ary_obj_edit_data_list.length - 1];
                var str_remove_edit_id = obj_remove_edit.get_dom_id();

                $("#" + str_remove_edit_id).parent().remove();
                m_ary_obj_edit_data_list.pop();
            }
        }

        var ary_edit_list = $("#" + m_str_box_id + " .edit_list").children();

        for (var idx = 0; idx < ary_edit_list.length; idx++) {
            var ui_data_idx = Math.floor(idx / 4);
            var ui_grp_idx = idx % 4;

            ary_edit_list.eq(idx).children().attr("data_idx",ui_data_idx);
            ary_edit_list.eq(idx).children().attr("grp_idx",ui_grp_idx);
        }
        m_ui_line_len = ui_line_len;

        return 1;
    };
    /**
     * 更新列表内容
     * @param {Number} ui_top_idx 当前限制行最大idx
     */
    this.updata_table_val = function (ui_top_idx) {
        m_ui_top_line_idx = ui_top_idx;
        // 修改侧边列表
        for (var idx_left_list = 0; idx_left_list < m_ary_obj_edit_idx_list.length; idx_left_list++) {
            var obj_edit_left = m_ary_obj_edit_idx_list[idx_left_list];

            obj_edit_left.set_dom_val((ui_top_idx + idx_left_list).toString(16));
        }
        var ui_top_data_idx = ui_top_idx * m_ui_line_len;
        var obj_edit_list_dom = $("#" + m_str_box_id + " .edit_list");

        // 修改数据列表
        for (var idx_data = 0; idx_data < m_ary_obj_edit_data_list.length; idx_data++) {
            var obj_edit_data = m_ary_obj_edit_data_list[idx_data];
            var obj_edit_id = obj_edit_data.get_dom_id();
            var obj_edit_dom = obj_edit_list_dom.find("#" + obj_edit_id);
            var ui_data_idx_dom = Number(obj_edit_dom.attr("data_idx"));
            var ui_grp_idx_dom = Number(obj_edit_dom.attr("grp_idx"));
            var ui_data_idx = ui_top_data_idx + ui_data_idx_dom;
            var ary_data = m_ary_data[Math.floor(ui_data_idx)];

            if (m_ui_table_type) {
                obj_edit_data.set_dom_type("hex");
                obj_edit_data.set_dom_disabled(false);
            }

            if (!ary_data) {
                obj_edit_data.set_dom_type("none");
                obj_edit_data.set_dom_val("");
                obj_edit_data.set_dom_disabled(true);
                continue;
            }
            obj_edit_data.set_dom_val(ary_data[ui_grp_idx_dom]);
        }
    };
    /**
     * 获取表格html字符串
     * @param {Number} ui_type 获取类型 0:对比参数(无法修改) 1:正常输出
     * @returns {String} 表格html字符串
     */
    this.get_html = function (ui_type) {
        m_ui_table_type = ui_type;
        m_ary_obj_edit_data_list = [];
        m_ary_obj_edit_idx_list = [];
        var str_edit_html = "";
        var str_line_html = "";

        // 限制显示行数
        var ui_show_line_max = Math.ceil((this.m_ui_window_h + 200) / 25);
        // 正常显示行数
        var ui_show_line_normal = Math.ceil(m_ui_data_len / m_ui_line_len);
        // 如果正常行数未超出则显示正常行数否则限制显示行数
        var ui_show_line = ui_show_line_max >= ui_show_line_normal ? ui_show_line_normal : ui_show_line_max;

        for (var idx_line_len = 0; idx_line_len < ui_show_line; idx_line_len++) {
            // 生成行下标编辑框内容从0开始生成
            var obj_edit_line = new mc_ui_edit();

            obj_edit_line.set_style_width("58px");
            obj_edit_line.set_style_height("23px");
            obj_edit_line.set_disabled(true);
            obj_edit_line.set_val(idx_line_len.toString(16));
            str_line_html += obj_edit_line.get_html_txt();
            m_ary_obj_edit_idx_list.push(obj_edit_line);

            for (var idx_data = 0; 4 * m_ui_line_len > idx_data; idx_data++) {
                var ui_data_idx = (idx_line_len * m_ui_line_len) + Math.floor(idx_data / 4);
                var ui_grp_idx = idx_data % 4;
                var ary_edit_val = m_ary_data[ui_data_idx];
                var obj_edit_data = new mc_ui_edit();

                obj_edit_data.set_type("hex");
                obj_edit_data.set_style_width("23px");
                obj_edit_data.set_style_height("23px");
                obj_edit_data.set_max_val("ff");
                obj_edit_data.set_min_val("00");
                obj_edit_data.set_default_digit(2);
                obj_edit_data.set_add_attr([["data_idx",ui_data_idx.toString()],["grp_idx",(ui_grp_idx).toString()]]);
                if (!ui_type || !ary_edit_val) {
                    obj_edit_data.set_disabled(true);
                }
                if (ary_edit_val) {
                    var str_edit_val = ary_edit_val[ui_grp_idx];

                    if (ui_type) {
                        obj_edit_data.on_val_chg = m_mc_edit_on_val_chg;
                    }
                    obj_edit_data.set_val(str_edit_val);
                }
                str_edit_html += obj_edit_data.get_html_txt();
                m_ary_obj_edit_data_list.push(obj_edit_data);
            }
        }

        var ui_window_height = 25 * Math.ceil(m_ui_data_len / m_ui_line_len);
        var str_html = "<div class=\"table_box\">" +
                            "<div class=\"scroll_len\" style=\"height:" + ui_window_height + "px;\">" +
                                "<div class=\"table_content\">" +
                                    "<div class=\"data_line_idx\">" + str_line_html + "</div>" +
                                    "<div class=\"edit_list\" style=\"width:" + m_ui_line_len * 100 + "px;\">" + str_edit_html + "</div>" +
                                "</div>" +
                            "</div>" +
                        "</div>";

        return str_html;
    };
    /**
     * 写入指定长度的数据
     * @param {Array} ary_data 写入数据
     * @param {Number} ui_mdf_len 写入长度
     */
    this.set_data = function (ary_data,ui_mdf_len) {
        for (var idx = 0; idx < ui_mdf_len; idx++) {
            m_ary_data[idx] = ary_data.slice();
        }
        this.updata_table_val(m_ui_top_line_idx);
    };

    /**
     * 获取发送数据
     * @param {Number} ui_get_type 获取类型(0:不使用换行符,1:使用换行符)
     * @returns {String} 发送数据
     */
    this.get_send_data = function (ui_get_type) {
        var str_data = "";

        for (var idx_data = 0; idx_data < m_ary_data.length; idx_data++) {
            var ary_grp = m_ary_data[idx_data];

            for (var idx_grp = 0; idx_grp < ary_grp.length; idx_grp++) {
                str_data += ary_grp[idx_grp];
            }
            if (ui_get_type) {
                str_data += "\n";
            }
        }
        return str_data;
    };
    /**
     * 存入发送数据
     * @param {String} str_send_data 回读发送数据
     */
    this.set_send_data = function (str_send_data) {
        if (0 !== str_send_data.length % 8) {
            str_send_data = str_send_data.slice(0,(Math.floor(str_send_data.length / 8)));
        }
        var ary_data = [];

        for (var idx = 0; idx < str_send_data.length; idx += 8) {
            ary_data.push([
                str_send_data[idx] + str_send_data[idx + 1],
                str_send_data[idx + 2] + str_send_data[idx + 3],
                str_send_data[idx + 4] + str_send_data[idx + 5],
                str_send_data[idx + 6 ] + str_send_data[idx + 7]
            ]);
        }
        this.set_data_len(ary_data.length);
        m_ary_data = ary_data;
    };
    /* **************************************** 内部函数 **************************************** */
    /************************************************************************************************
     * 类型:
     *    内部函数
     * 功能:
     *    编辑框更新事件
     * 参数:
     *    @param {Promise<String>} id 控件id
     *    @param {Promise<String>} val 控件更新内容
     * 返回：
     *    NA
     * 修改:
     *   1. 类型 : 创建
     *      作者 : 徐烁超
     *      时间 : 2020.11.26
     *      内容 : 所有代码
     ************************************************************************************************/
    function m_mc_edit_on_val_chg(id,val) {
        var obj_this = $("#" + id);
        // 属于数据列表中的第几组数据 每四个数据为一组
        var ui_data_idx = obj_this.attr("data_idx");
        var ui_grp_idx = obj_this.attr("grp_idx");
        var ui_top_data_idx = m_ui_top_line_idx * m_ui_line_len;

        var ui_updata_data_idx = ui_top_data_idx + Number(ui_data_idx);

        m_ary_data[ui_updata_data_idx][ui_grp_idx] = 1 < val.length ? val : "0" + val;
    }
}

/************************************************************************************************
* 类型:
*    函数
* 功能:
*    数据读写列表绑定事件
* 参数:
*    @param {Promise<Object>} obj_table 绑定对象
*    @param {Promise<String>} id 绑定dom
* 返回：
*    NA
* 修改:
*   1. 类型 : 创建
*      作者 : 徐烁超
*      时间 : 2020.11.27
*      内容 : 所有代码
************************************************************************************************/
function mc_hwdata_scroll_fun(obj_table,id) {
    $("#" + id + " .table_box").scroll(function () {
        // 获取父盒子
        var obj_this_dom = $(this);
        var ui_scroll_top = obj_this_dom.scrollTop();
        var obj_content_dom = obj_this_dom.find(".table_content");
        var ui_top_line_idx = Math.ceil(ui_scroll_top / 25) - 5;
        var ui_max_line_idx = obj_table.get_max_bottom_line();

        if (0 > ui_top_line_idx) {
            ui_top_line_idx = 0;
        }
        if (ui_max_line_idx < ui_top_line_idx) {
            ui_top_line_idx = ui_max_line_idx;
        }
        mc_hwdata_table_int(obj_table,false,ui_top_line_idx);
        obj_content_dom.css("top", (ui_top_line_idx * 25) + "px");
    });
}

/************************************************************************************************
* 类型:
*    函数
* 功能:
*    更新列表行数数据与排列方式
* 参数:
*    @param {Promise<Object>} obj_table 绑定对象
*    @param {Promise<Number>} ui_line_len 单行显示长度
*    @param {Promise<Number>} ui_top_idx 限制列表最高层下标
* 返回：
*    NA
* 修改:
*   1. 类型 : 创建
*      作者 : 徐烁超
*      时间 : 2020.11.27
*      内容 : 所有代码
************************************************************************************************/
function mc_hwdata_table_int(obj_table,ui_line_len,ui_top_idx) {
    if ("number" === typeof ui_line_len ) {
        obj_table.set_line_len_dom(ui_line_len);
    }
    if ("number" === typeof ui_top_idx ) {
        obj_table.updata_table_val(ui_top_idx);
    }
}
